//
//  LZAVPlayerManager.m
//  LZMusicPlayer
//
//  Created by wulanzhou on 2016/10/18.
//  Copyright © 2016年 wulanzhou. All rights reserved.
//

#import "LZAVPlayerManager.h"

@interface LZAVPlayerManager (){

    id timeObserve;
    AVPlayer *_avPlayer;
    
    NSInteger      _currentPlayIndex;
    NSMutableArray <NSURL *> *_musicList;
}
@end

@implementation LZAVPlayerManager

@synthesize player=_avPlayer;

+ (LZAVPlayerManager *)shareInstance{
    static dispatch_once_t pred = 0;
    __strong static LZAVPlayerManager *_sharedObject = nil;
    dispatch_once(&pred, ^{
        _sharedObject = [[self alloc] init]; // or some other init method
    });
    return _sharedObject;
}

- (instancetype)init{

    if(self=[super init]){
        _currentPlayIndex=0;
        _musicList=[[NSMutableArray alloc] initWithCapacity:0];
        
        //后台播放音乐，设置音频的会话类型。必须真机演示
        AVAudioSession *ausioSession = [AVAudioSession sharedInstance];
        [ausioSession setCategory:AVAudioSessionCategoryPlayback error:NULL];
    }
    return self;
}

- (void)dealloc{

    [self removeAllObserves];
}

- (void)playingWithURL:(NSURL *)musicURL{

    if (musicURL == nil) {
        return;
    }
    
    __block BOOL isExists=NO;
    [_musicList enumerateObjectsUsingBlock:^(NSURL * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        
        if (obj==musicURL) {
            isExists=YES;
            *stop=YES;
        }
    }];
    
    if (!isExists) {
        [_musicList addObject:musicURL];
    }
    
    if ([_musicList indexOfObject:musicURL]!=_currentPlayIndex) {
        _currentPlayIndex=[_musicList indexOfObject:musicURL];
    }
    
    
    AVPlayerItem * songItem = [[AVPlayerItem alloc] initWithURL:musicURL];
    //监听播放状态
    [songItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
    //监听数据缓冲
    [songItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
    //监听是否播放完成
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackFinished:) name:AVPlayerItemDidPlayToEndTimeNotification object:songItem];
    
    if (!_avPlayer) {
        _avPlayer = [[AVPlayer alloc] initWithPlayerItem:songItem];
    }else{
        //上一首、下一首：
        [_avPlayer replaceCurrentItemWithPlayerItem:songItem];
    }
    
    [_avPlayer play];
    
    __weak LZAVPlayerManager *WSELF=self;
    
    //监听播放进度
    timeObserve=[self.player addPeriodicTimeObserverForInterval:CMTimeMake(1.0, 1.0) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
        
        float current = CMTimeGetSeconds(time);
        float total = CMTimeGetSeconds(songItem.duration);
        if (current) {
            //weakSelf.progress = current / total;
            //weakSelf.playTime = [NSString stringWithFormat:@"%.f",current];
            //weakSelf.playDuration = [NSString stringWithFormat:@"%.2f",total];
            
            NSLog(@"播放进度 progress=%f,playTime=%@,playDuration =%@",current / total,[NSString stringWithFormat:@"%.f",current],[NSString stringWithFormat:@"%.2f",total]);
            
            if (WSELF.delegate&&[WSELF.delegate respondsToSelector:@selector(playMusicProgress:playTime:playDuration:)]) {
                [WSELF.delegate playMusicProgress:current / total playTime:current playDuration:total];
            }

        }
    }];
    
    
}

- (void)playingWithURLs:(NSArray <NSURL *> *)urls{

    if (urls&&[urls count]>0) {
        
        [_musicList addObjectsFromArray:urls];
        
        NSURL *firstURL=[urls objectAtIndex:0];
        
        [self playingWithURL:firstURL];
        
    }
}

#pragma mark -上一首，下一首

- (void)prevMusic{
    
    if ([_musicList count]==0) {
        return;
    }
    
    if (_currentPlayIndex!=0) {
        _currentPlayIndex--;
        if (_currentPlayIndex<0) {
            _currentPlayIndex=0;
        }
        
        if (_currentPlayIndex<[_musicList count]) {
            NSURL *preURL=[_musicList objectAtIndex:_currentPlayIndex];
            [self playingWithURL:preURL];
        }
    }

}
- (void)nextMusic{

    if ([_musicList count]==0) {
        return;
    }
    
    if (_currentPlayIndex!=[_musicList count]-1) {
        _currentPlayIndex++;
        if (_currentPlayIndex>[_musicList count]-1) {
            _currentPlayIndex=[_musicList count]-1;
        }
        
        if (_currentPlayIndex<[_musicList count]) {
            NSURL *preURL=[_musicList objectAtIndex:_currentPlayIndex];
            [self playingWithURL:preURL];
        }
    }
}

- (void)reset{

    _currentPlayIndex=0;
    [_musicList removeAllObjects];
    if(_avPlayer){
        [_avPlayer pause];
    }
    [self removeAllObserves];
    _avPlayer=nil;
    
}

#pragma mark -移除监听
- (void)removeAllObserves{

    [[NSNotificationCenter defaultCenter] removeObserver:self name:AVPlayerItemDidPlayToEndTimeNotification object:self.player.currentItem];
    [self.player.currentItem removeObserver:self forKeyPath:@"status"];
    [self.player.currentItem removeObserver:self forKeyPath:@"loadedTimeRanges"];
    if (timeObserve) {
        [self.player removeTimeObserver:timeObserve];
        timeObserve = nil;
    }
    
}

#pragma mark -播放完成
- (void)playbackFinished:(NSNotification *)notice {
    //BASE_INFO_FUN(@"播放完成");

    NSLog(@"播放完成,object=%@,useInfo=%@",[notice.object class],notice.userInfo);
    
    //移除监听
    [self removeAllObserves];
    
    //下一首
    [self nextMusic];
    
}



#pragma mark -准备播放的状态
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
    
    
    NSLog(@"observeValueForKeyPath =%@,object=%@",keyPath,[object class]);
    
    if ([object isMemberOfClass:[AVPlayer class]]) {
        
        NSLog(@"是相同的实例对象!!!");
    }
    
    if ([keyPath isEqualToString:@"status"]) { //准备播放的状态
        switch (self.player.status) {
            case AVPlayerStatusUnknown:{
            
                NSLog(@"KVO：未知状态，此时不能播放");
                break;
            }
                
            case AVPlayerStatusReadyToPlay:{
            
                //self.status = SUPlayStatusReadyToPlay;
                NSLog(@"KVO：准备完毕，可以播放");
                //[self.player play];
                break;
            }
                
            case AVPlayerStatusFailed:{
            
                NSLog(@"KVO：加载失败，网络或者服务器出现问题");
                break;
            }
                
            default:
                break;
        }
    }
    
    if ([keyPath isEqualToString:@"loadedTimeRanges"]) { //数据缓冲状态
        NSArray * array = self.player.currentItem.loadedTimeRanges;
        CMTimeRange timeRange = [array.firstObject CMTimeRangeValue]; //本次缓冲的时间范围
        NSTimeInterval totalBuffer = CMTimeGetSeconds(timeRange.start) + CMTimeGetSeconds(timeRange.duration); //缓冲总长度
        NSLog(@"共缓冲%.2f",totalBuffer);
    }
}

@end
